% ML TAU 2013 final project script
% Alt 9:
% Stacking impl: Split the data to 2 equal parts. use one half to train 21 different SVMs. 
% Make predictions on the other half to create a new set of data to be learned by another SVM.

% base_path = '/home/itay/TAU/IML/final';
% libsvm_path = '/opt/libsvm-3.17/matlab';

% Add path to the libsvm
% addpath(base_path);
% addpath(libsvm_path);

function gogo_alt9()


    %
    % Initialization
    %
    close all; clear; clc; tic;
    
    L = 3; H = 120; N = 100;
    
    if ~exist('dataforproject.mat','file')
        error('Data file not found in current directory')
    end;
    
    % Saving memory. Loading vars on a need to load basis only throughout
    load('dataforproject.mat','X1train','X2train','gidtrain','ytrain');
    fprintf('Training Data successfully loaded\n');

    X_DELTA = abs(X1train-X2train);

    [n,M] = size(X_DELTA);
    
    X_NORM = X_DELTA/max(X_DELTA(:));

    [X_PC COEFF SCORE latent] = basic_PCA(X_NORM', n, 'X1train-X2train');
    
    X = X_PC(:,L:H);
    
    if ~exist(sprintf('best_%d_results.mat',N),'file')
        error('Data file not found in current directory')
    end;
    load(sprintf('best_%d_results.mat',N),'best_results');

    
    fraction = 0.5;
    
    Data = zeros(M*fraction,N);
   
    X1 = X((gidtrain==1),:);
    X2 = X((gidtrain==2),:);
    X3 = X((gidtrain==3),:);

    y1 = ytrain(gidtrain==1);
    y2 = ytrain(gidtrain==2);
    y3 = ytrain(gidtrain==3);

    m = (M*fraction)/3; M = M/3;
    
    S1 = [X1(1:m,:);X2(1:m,:);X3(1:m,:)];
    S2 = [X1(m+1:M,:);X2(m+1:M,:);X3(m+1:M,:)];
 
    L1 = [y1(1:m,:);y2(1:m,:);y3(1:m,:)];
    L2 = [y1(m+1:M,:);y2(m+1:M,:);y3(m+1:M,:)];

    GID = [repmat(1,[m 1]);repmat(2,[m 1]);repmat(3,[m 1])];

    if ~exist(sprintf('stacking_best_%d.mat',N),'file')

    for j=1:N

        params = best_results(j,:); % [L H C D T Err]
        
        c = params(3); d = params(4); t = params(5); 
                         
        % Create the model
        model = svmtrain(L2,S2,sprintf('-t %d -g  1.0 -c %f -d %d -h 0 -q',t,c,d));
            
        % Predict
        Data(:,j) = svmpredict(L1,S1,model);
    end

        save(sprintf('stacking_best_%d.mat',N),'Data');

    else
        load(sprintf('stacking_best_%d.mat',N),'Data'); 
    end    

    % (C*=0.015625 ; t*=0 ; deg*=1)
    T = 0; C = 0.015625; D = 1;
    do_svm(Data,L1,GID,T,C,D);

    %svm_grid_search(Data,L1,GID);
    
function [accuracy] = do_svm(S,L,GID,T,C,D)

    accuracy = 0.0;

    for k=1:3
        
       % Training set
       X_train = S((GID~=k),:);
       y_train = L(GID~=k);
       
       % Testing set
       X_test = S((GID==k),:);
       y_test = L(GID==k);

       model = svmtrain(y_train,X_train,sprintf('-t %d -g  1.0 -c %f -d %d -h 0 -q',T,C,D));
       
       predictedY = svmpredict(y_test,X_test,model);
      
       results = sum(y_test.*predictedY > 0) / size(y_test,1);
        
       accuracy = accuracy+results;
        
    end
    
    accuracy = accuracy/3;
    
    fprintf('#Avg Acc: %f\n',accuracy);

end




function [C D T Err] = svm_grid_search(DATA,L,GID)


    ker_degrees = 1:1;%1:4;

    ker_types = 0:0;%0:3;

    c_degrees = -10:4;%-3:7;
    
    s = size (c_degrees);
    
    c_vec = power(repmat(2,s),c_degrees);   
 
    Err = 1.0;
    
for  ker=ker_types
   
    for deg=ker_degrees
        
        for margin=c_vec
            
            e = 1-do_svm(DATA,L,GID,ker,margin,deg); 
            if e < Err
                C=margin; D=deg; T=ker; Err=e;
            end
        end
    end
end

fprintf('===\tResults\t===\n(C*=%f ; t*=%d ; deg*=%d)\n#Avg Acc: %f\n',C,T,D,1-Err);

end


    
end

